package com.amgl.recyclerviewwithheaderfooter;

import android.support.annotation.IntDef;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * RecyclerView Scroll 滑动监听
 * 到最后一项时调用isScrollToLast()
 * Item数为0时不调用
 * <p/>
 * Created by amglh on 2016/8/10.
 */
public abstract class ScrollToLastItemListener extends RecyclerView.OnScrollListener {
    private static final int TYPE_INVALID = -1;
    private static final int TYPE_LINEAR_LAYOUT_MANAGER = 0;
    private static final int TYPE_GRID_LAYOUT_MANAGER = 1;
    private static final int TYPE_STAGGERED_LAYOUT_MANAGER = 2;


    @IntDef({TYPE_INVALID, TYPE_LINEAR_LAYOUT_MANAGER, TYPE_GRID_LAYOUT_MANAGER, TYPE_STAGGERED_LAYOUT_MANAGER})
    @Retention(RetentionPolicy.SOURCE)
    public @interface LayoutManagerType {
    }

    @IntDef({RecyclerView.SCROLL_STATE_IDLE, RecyclerView.SCROLL_STATE_DRAGGING, RecyclerView.SCROLL_STATE_SETTLING})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ScrollState {
    }

    @ScrollState
    int mCurrentScrollState = RecyclerView.SCROLL_STATE_IDLE;

    @LayoutManagerType
    int mLayoutManagerType = TYPE_INVALID;

    /**
     * 最后一个可见的item的位置
     */
    private int mLastVisiblePosition;

    private LinearLayoutManager mLinearLayoutManager = null;
    private GridLayoutManager mGridLayoutManager = null;
    private StaggeredGridLayoutManager mStaggeredGridLayoutManager = null;

    /**
     * 最后可见位置（StaggeredGridLayoutManager）
     */
    private int[] lastPositions;

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();

        //根据不同的LayoutManager，得到LastVisibleItem的位置
        if (mLayoutManagerType == TYPE_INVALID) {
            if (layoutManager instanceof LinearLayoutManager) {
                mLayoutManagerType = TYPE_LINEAR_LAYOUT_MANAGER;
                mLinearLayoutManager = (LinearLayoutManager) layoutManager;
            } else if (layoutManager instanceof GridLayoutManager) {
                mLayoutManagerType = TYPE_GRID_LAYOUT_MANAGER;
                mGridLayoutManager = (GridLayoutManager) layoutManager;

            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                mLayoutManagerType = TYPE_STAGGERED_LAYOUT_MANAGER;
                mStaggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
            } else {
                throw new RuntimeException(
                        "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager");
            }
        }
        switch (mLayoutManagerType) {
            case TYPE_LINEAR_LAYOUT_MANAGER:
                mLastVisiblePosition = mLinearLayoutManager.findLastVisibleItemPosition();
                break;
            case TYPE_GRID_LAYOUT_MANAGER:
                mLastVisiblePosition = mGridLayoutManager.findLastVisibleItemPosition();
                break;
            case TYPE_STAGGERED_LAYOUT_MANAGER:
                if (lastPositions == null) {
                    lastPositions = new int[mStaggeredGridLayoutManager.getSpanCount()];
                }
                mStaggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
                mLastVisiblePosition = findMax(lastPositions);
                break;
        }
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        mCurrentScrollState = newState;
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        int visibleItemCount = layoutManager.getChildCount();
        int totalItemCount = layoutManager.getItemCount();

        //滚动状态IDLE&&当前显示的是最后一项&&显示总的Item数不为0
        if (mCurrentScrollState == RecyclerView.SCROLL_STATE_IDLE && mLastVisiblePosition >= totalItemCount - 1 && visibleItemCount > 0) {
            isScrollToLast(mLastVisiblePosition);
        }
    }

    /**
     * 取数组中最大值
     *
     * @param lastPositions
     * @return
     */
    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }

    /**
     * 已经滚动到最后一项
     */
    protected abstract void isScrollToLast(int lastVisiblePosition);
}
